package server;
import java.util.*;

import msgs.*;

/**
 * Updates a chat based on a client action
 * Team 9: Andrew Hayworth, Brian Parrella, Ryan Kortmann, Nina Papa
 * @author Andrew Hayworth
 */

public class ChatHandler extends Thread implements TTConstants {
	private ChatMsg cmsg;
	
	public ChatHandler(ClientMsg cmsg) {
		this.cmsg = (ChatMsg) cmsg;
	}
	
	public void run() {
		// ooooook find out what they want to do
		switch(cmsg.getAction()) {
		case LEAVE_CHAT:
			//auth
			if (!(Arrays.equals(cmsg.getClientKey(), TTServer.connTable.get(cmsg.getName()).getClientKey()))) {
				cmsg.setResponse(Responses.DENY);
				ClientSender.outQ.add((ClientMsg) cmsg);
				return;
			}
			if (TTServer.chats.get(((ChatMsg)cmsg).getTitle()).getMemberNames().contains(cmsg.getName())) {
				TTServer.chats.get(((ChatMsg)cmsg).getTitle()).removeUser(cmsg.getName());
				cmsg.setResponse(Responses.OK);
				ClientSender.outQ.add((ClientMsg) cmsg);
				return;
			}
			break;
		case CHAT_UPDATE:
			// auth
			if (!(Arrays.equals(cmsg.getClientKey(), TTServer.connTable.get(cmsg.getName()).getClientKey()))) {
				cmsg.setResponse(Responses.DENY);
				ClientSender.outQ.add((ClientMsg) cmsg);
				return;
			}
			// ugly workaround follows
			// .... but now, I'm not sure what I was working around. It functions, so leaving it alone
			ArrayList<String> a = new ArrayList<String>();
			for (ConnectedUser t : TTServer.chats.get(cmsg.getTitle()).getMembers()) {
				a.add(t.getName());
			}
			if (a.contains(cmsg.getName())) {
				TTServer.chats.get(cmsg.getTitle()).addMsg(cmsg.getName(), cmsg.getMsg());
				cmsg.setResponse(Responses.OK);
			}
			else {
				cmsg.setResponse(Responses.DENY);
			}
			break;
		case KILL_CHAT:
			//auth
			if (!(Arrays.equals(cmsg.getClientKey(), TTServer.connTable.get(cmsg.getName()).getClientKey()))) {
				cmsg.setResponse(Responses.DENY);
				ClientSender.outQ.add((ClientMsg) cmsg);
				return;
			}
			// only kill if we're an admin
			if(TTServer.chats.get(cmsg.getTitle()).getAdmins().contains(cmsg.getName())) {
				synchronized(TTConstants.lock) {
					TTServer.chats.remove(cmsg.getTitle());	//pulls it out
				}
				cmsg.setResponse(Responses.OK);
				ClientSender.outQ.add((ClientMsg) cmsg);
				return;
			}
		case JOIN_CHAT:
			//auth
			if (!(Arrays.equals(cmsg.getClientKey(), TTServer.connTable.get(cmsg.getName()).getClientKey()))) {
				cmsg.setResponse(Responses.DENY);
				ClientSender.outQ.add((ClientMsg) cmsg);
				return;
			}
			// make sure this chat even exists
			if (!(TTServer.chats.containsKey(cmsg.getTitle()))) {
				cmsg.setResponse(Responses.DENY);
				ClientSender.outQ.add((ClientMsg)cmsg);
				return;
			}
			//make sure it's not closed
			if (TTServer.chats.get(cmsg.getTitle()).isClosed() || !(TTServer.chats.containsKey(cmsg.getTitle()))) {
				cmsg.setResponse(Responses.DENY);
				ClientSender.outQ.add((ClientMsg) cmsg);
				return;
			}
			//UGLY HACK(s)
			// make sure they're allowed to be in here
			ArrayList<String> a2 = new ArrayList<String>();
			for (ConnectedUser t : TTServer.chats.get(cmsg.getTitle()).getMembers()) {
				a2.add(t.getName());
			}
			synchronized(TTConstants.lock) {
				if (!(a2.contains(cmsg.getName()))) {
					// cool, add them
					TTServer.chats.get(cmsg.getTitle()).addUser(cmsg.getName());
				}
			}
			cmsg.setResponse(Responses.OK);
			cmsg.setMembers(a2);
			ClientSender.outQ.add((ClientMsg) cmsg);
			return;
		case NEW_CHAT:
			//auth
			if (!(Arrays.equals(cmsg.getClientKey(), TTServer.connTable.get(cmsg.getName()).getClientKey()))) {
				cmsg.setResponse(Responses.DENY);
				ClientSender.outQ.add((ClientMsg) cmsg);
				return;
			}
			
			// deny if we have a chat by this title already
			if (TTServer.chats.containsKey(cmsg.getTitle())) {
				cmsg.setResponse(Responses.DENY);
				ClientSender.outQ.add((ClientMsg) cmsg);
				return;
			}
			// lets make us a chat
			// only actually add users if they're onlin at the time. they can always joing later though
			ArrayList<ConnectedUser> members = new ArrayList<ConnectedUser>();
			for (String name : (ArrayList<String>) cmsg.getMembers()) {
				if (TTServer.connTable.containsKey(name)) {
					members.add(TTServer.connTable.get(name));
				}
			}
			Chat c = new Chat(members, cmsg.getAdmins(), cmsg.getTitle(), cmsg.isClosed());
			c.start();
			TTServer.chats.put(cmsg.getTitle(), c);
			cmsg.setResponse(Responses.OK);
			ClientSender.outQ.add((ClientMsg) cmsg);
			return;
		}
	}
}
